package com.zmn.oms.business.impl.work.erp;

import com.google.common.collect.Lists;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.map.Point;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.business.interfaces.es.OrderWorkEsBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.work.erp.OrderAccountInfoListBService;
import com.zmn.oms.business.interfaces.work.tag.OrderTagBService;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.FilterUtil;
import com.zmn.oms.common.utils.MathUtil;
import com.zmn.oms.model.dto.work.OrderPartSettleSubjectInfo;
import com.zmn.oms.model.dto.work.erp.*;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.discount.OrderDiscount;
import com.zmn.oms.model.entity.factory.OrderFactory;
import com.zmn.oms.model.entity.master.OrderMaster;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.part.OrderPart;
import com.zmn.oms.model.entity.pay.OrderPay;
import com.zmn.oms.model.entity.remark.OrderRemarkDetail;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.wallquotation.WallQuotationQuery;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.conf.workturn.bizmode.PlatBizModeService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.discount.OrderDiscountService;
import com.zmn.oms.services.interfaces.factory.OrderFactoryService;
import com.zmn.oms.services.interfaces.master.OrderMasterService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.part.OrderPartService;
import com.zmn.oms.services.interfaces.pay.OrderPayService;
import com.zmn.oms.services.interfaces.remark.OrderRemarkDetailService;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.services.interfaces.wallquotation.WallQuotationService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sunlife
 * @date:2021/7/22 4:58 下午
 * description: 算账信息
 */
@Slf4j
@Service
public class OrderAccountInfoListBServiceImpl implements OrderAccountInfoListBService {

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OrderExtendService orderExtendService;
    @Autowired
    private OrderFactoryService orderFactoryService;
    @Autowired
    private OrderDiscountService orderDiscountService;
    @Autowired
    private OrderPayService orderPayService;
    @Autowired
    private OrderServiceItemService orderServiceItemService;
    @Autowired
    private OrderMasterService orderMasterService;
    @Autowired
    private OrderPartService orderPartService;
    @Autowired
    private BaiduMapBService baiduMapBService;
    @Autowired
    private OrderTagBService orderTagBService;
    @Autowired
    private ServItemBService servItemBService;
    @Autowired
    private OrderRemarkDetailService orderRemarkDetailService;
    @Autowired
    private OrderWorkEsBService orderWorkEsBService;
    @Autowired
    private WallQuotationService wallQuotationService;
    @Resource
    private PlatBizModeService platBizModeService;

    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ChannelListRemoteService channelListRemoteService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private AreaListRemoteService areaListRemoteService;

    @Override
    public NewOrderAccountInfoDTO getNewOrderAccountInfo(OrderWork orderWork) throws OmsBaseException {
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKeySrcMaster(orderWork.getWorkId());

        // 工单信息设置
        NewOrderAccountInfoDTO newOrderAccountDTO = BeanMapper.map(orderWork, NewOrderAccountInfoDTO.class);

        newOrderAccountDTO.setOrderType(orderWork.getType());
        newOrderAccountDTO.setOrderCityId(orderWork.getCityId());
        newOrderAccountDTO.setOrderCityName(orderDetail.getCityName());
        newOrderAccountDTO.setPlatSource(orderWork.getPlat());
        newOrderAccountDTO.setPlat(orderWork.getPlatWork());
        newOrderAccountDTO.setSubCompanyId(orderWork.getCompanyId());
        newOrderAccountDTO.setSubCompanyName(orderWork.getCompanyName());
        newOrderAccountDTO.setSpCompanyId(orderWork.getManageCompanyId());
        newOrderAccountDTO.setSpCompanyName(orderWork.getManageCompanyName());
        newOrderAccountDTO.setProductGroupId(orderWork.getServProductGroupId());
        newOrderAccountDTO.setProductGroupName(orderWork.getServProductGroupName());
        newOrderAccountDTO.setOrderSourceType(orderWork.getSourceType());
        newOrderAccountDTO.setServCategName(orderWork.getShowServCategName());

        // 次卡金额
        newOrderAccountDTO.setTimesCardAmount(orderWork.getDiscountPrepayAmount());

        // 支付优惠金额
        newOrderAccountDTO.setPaymentDiscountAmount(orderWork.getPayDiscountAmount());

        newOrderAccountDTO.setUserName(orderDetail.getUserName());
        newOrderAccountDTO.setEngSupervisorId(orderWork.getMasterSupervisorId());
        newOrderAccountDTO.setEngSupervisorName(orderWork.getMasterSupervisorName());
        newOrderAccountDTO.setOrderSuccessful(Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_SUCCESS));
        newOrderAccountDTO.setProductInf(orderDetail.getProductInfo());
        Integer reimburseStatus = orderWork.getPartReimburseStatus();
        newOrderAccountDTO.setPartsReimburseStatus(reimburseStatus);
        // 配件金额
        List<OrderPart> orderParts = orderPartService.listByOrderId(orderWork.getOrderId());
        Integer partAmount = orderParts.stream().mapToInt(part -> {
            return MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber());
        }).sum();
        newOrderAccountDTO.setPartAmount(partAmount);

        // 使用来源渠道sourceChannelId（专门用来做结算使用） 进行erp算账
        // 默认情况下 sourceChannelId 和 channelId 是相同的 只有营销推广业务这种sourceChannelId 和 channelId不同
        // 不同 eg. 通过啄金客账户推广 用户扫推广码码到我们微信公众号下的定单 sourceChannelId 是啄金客二级渠道 channelId 就是微信公众号二级渠道
        Integer channel = NumberUtil.isNullOrZero(orderWork.getSourceChannelId()) ?
                orderWork.getChannelId() :
                orderWork.getSourceChannelId();
        newOrderAccountDTO.setChannelId(channel);
        ResponseDTO<ChannelDRO> channelDROResponseDTO = channelListRemoteService.getByChannelId(channel);
        if (channelDROResponseDTO.isSuccess()) {
            newOrderAccountDTO.setChannelName(channelDROResponseDTO.getData().getName());
        }


        // 厂商id
        if (Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)) {
            OrderFactory orderFactory = orderFactoryService.findOrderFactoryByKey(orderWork.getOrderId());
            if (orderFactory != null) {
                newOrderAccountDTO.setFactoryId(orderFactory.getFactoryId());
            }
        }

        // 行车距离
        // 获取区县经纬度
        ResponseDTO<AreaDRO> areaDROResponseDTO = areaListRemoteService.getById(orderDetail.getCountyId());
        if (areaDROResponseDTO.isSuccess()) {
            Point point1 = new Point(areaDROResponseDTO.getData().getLongitude(), areaDROResponseDTO.getData().getLatitude());
            Point point2 = new Point(orderDetail.getLongitude(), orderDetail.getLatitude());
            newOrderAccountDTO.setDistanceValue(baiduMapBService.getNavigationDistance(point1, point2));
        }

        // 处理工程师信息
        // 当前工单多工程师处理
        // 查询工程师列表
        List<OrderMaster> orderMasterList = orderMasterService.listMasterByWorkId(orderWork.getOrderId(), orderWork.getWorkId());
        Map<Integer, List<OrderPart>> partMap = orderParts.stream()
                .collect(Collectors.groupingBy(OrderPart::getMasterId));

        // TODO liuying 多师傅状态数据修复
        if (orderMasterList.size() > 1 && !Objects.equals(orderWork.getMultiMaster(), GlobalConsts.YES)) {
            OrderWork updateOrderWork = new OrderWork();
            updateOrderWork.setOrderId(orderWork.getOrderId());
            updateOrderWork.setWorkId(orderWork.getWorkId());
            updateOrderWork.setMultiMaster(GlobalConsts.YES);
            updateOrderWork.setUpdater(com.zmn.common.constant.GlobalConsts.getOperatorTypeName(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
            updateOrderWork.setUpdateTime(DateUtil.getNow());
            orderWorkService.saveMultiMaster(updateOrderWork);

            orderWork.setMultiMaster(GlobalConsts.YES);
        } else if (orderMasterList.size() == 1 && !Objects.equals(orderWork.getMultiMaster(), GlobalConsts.NO)) {
            OrderWork updateOrderWork = new OrderWork();
            updateOrderWork.setOrderId(orderWork.getOrderId());
            updateOrderWork.setWorkId(orderWork.getWorkId());
            updateOrderWork.setMultiMaster(GlobalConsts.NO);
            updateOrderWork.setUpdater(com.zmn.common.constant.GlobalConsts.getOperatorTypeName(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
            updateOrderWork.setUpdateTime(DateUtil.getNow());
            orderWorkService.saveMultiMaster(updateOrderWork);

            orderWork.setMultiMaster(GlobalConsts.NO);
        }

        List<OrderAccountEngineerDTO> multiMasters = new ArrayList<>(orderMasterList.size());
        orderMasterList.forEach(orderMaster -> {
            OrderAccountEngineerDTO engineerDTO = new OrderAccountEngineerDTO();
            engineerDTO.setEngineerId(orderMaster.getMasterId());
            engineerDTO.setEngineerName(orderMaster.getMasterName());
            engineerDTO.setMajorEngineer(Objects.equals(orderMaster.getType(), OrderConsts.ORDER_MASTER_TYPE_MAIN));
            if (Objects.equals(orderWork.getMultiMaster(), GlobalConsts.YES)) {
                engineerDTO.setShareRate(orderMaster.getShareRateBigDecimal());
            } else {
                engineerDTO.setShareRate(new BigDecimal(100));
            }

            List<OrderPart> orderMasterParts = partMap.get(orderMaster.getMasterId());
            if (CollectionUtil.isNotNullOrEmpty(orderMasterParts)) {
                // 内采&非质保金购买
                Integer noDepositpartAmount = orderMasterParts.stream().filter(part -> Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_IN) && !Objects.equals(part.getPayType(), OrderPartConsts.DEPOSIT_PAY)).mapToInt(part -> {
                    return MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber());
                }).sum();
                // 内采&非质保金购买
                Integer masterSupPartAmount = orderMasterParts.stream().filter(part -> Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_IN) && Objects.equals(part.getPayType(), OrderPartConsts.DEPOSIT_PAY)).mapToInt(part -> {
                    return MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber());
                }).sum();

                engineerDTO.setPartAmount(noDepositpartAmount);
                engineerDTO.setPartAmountFromSup(masterSupPartAmount);

                // 非内采配件
                Integer otherPartAmount = orderMasterParts.stream().filter(part -> !Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_IN)).mapToInt(part -> {
                    return MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber());
                }).sum();
                engineerDTO.setOtherPartAmount(otherPartAmount);

                // 配件结算主体
                // 现金内采配件结算主体
                List<OrderPartSettleSubjectInfo> cashInsourcingPartAmountList = orderMasterParts.stream().filter(part -> {
                    return Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_IN) && !Objects.equals(part.getPayType(), OrderPartConsts.DEPOSIT_PAY);
                }).map(part -> {
                    OrderPartSettleSubjectInfo dio = new OrderPartSettleSubjectInfo();
                    dio.setPartsReimburseStatus(part.getReimburseStatus());
                    dio.setPartAmount(MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber()));
                    dio.setSettlementSubjectType(part.getSettlementSubjectType());
                    return dio;
                }).collect(Collectors.toList());
                engineerDTO.setCashInsourcingPartAmountList(cashInsourcingPartAmountList);

                // 外报配件结算主体
                List<OrderPartSettleSubjectInfo> outsourcingPartAmountList = orderMasterParts.stream().filter(part -> {
                    return Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_OUT);
                }).map(part -> {
                    OrderPartSettleSubjectInfo dio = new OrderPartSettleSubjectInfo();
                    dio.setPartsReimburseStatus(part.getReimburseStatus());
                    dio.setPartAmount(MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber()));
                    dio.setSettlementSubjectType(part.getSettlementSubjectType());
                    return dio;
                }).collect(Collectors.toList());
                engineerDTO.setOutsourcingPartAmountList(outsourcingPartAmountList);

                // 订单杂项费用结算主体
                List<OrderPartSettleSubjectInfo> otherPartAmountList = orderMasterParts.stream()
                        .filter(part -> Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_DELIVER))
                        .map(part -> {
                            OrderPartSettleSubjectInfo dio = new OrderPartSettleSubjectInfo();
                            dio.setPartsReimburseStatus(part.getReimburseStatus());
                            dio.setPartAmount(MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber()));
                            dio.setSettlementSubjectType(part.getSettlementSubjectType());
                            return dio;
                        })
                        .collect(Collectors.toList());
                engineerDTO.setOtherPartAmountList(otherPartAmountList);
            }

            multiMasters.add(engineerDTO);
        });
        newOrderAccountDTO.setEngineers(multiMasters);

        // 优惠券
        List<OrderDiscount> orderDiscounts = orderDiscountService.listByOrderId(orderWork.getOrderId()).stream().filter(discount -> NumberUtil.isNotNullOrZero(discount.getAmount())).collect(Collectors.toList());
        newOrderAccountDTO.setDiscountList(orderDiscounts);

        List<OrderPay> orderPayList = orderPayService.listOrderPayByOrderIdAndWorkId(orderWork.getOrderId(), orderWork.getWorkId());
        if (!CollectionUtils.isEmpty(orderPayList)) {
            List<OrderAccountPayDTO> erpOrderPayDTOS = Lists.newArrayList();
            orderPayList.forEach(e -> {
                if (Objects.equals(e.getDuplicate(), GlobalConsts.YES)) {
                    log.info("{}重复支付不算入erp算账", e.getOrderId());
                    return;
                }
                OrderAccountPayDTO erpOrderPayDTO = BeanMapper.map(e, OrderAccountPayDTO.class);
                erpOrderPayDTO.setPayChannelName(PayConsts.getPayChannelName(e.getPayChannelId()));
                erpOrderPayDTO.setPayTargetChannelId(e.getPayTargetChannelId());
                erpOrderPayDTO.setPayType(e.getPayType());
                boolean isPrepayAmt = Objects.equals(e.getAmountType(), OrderPayConsts.ORDER_PAY_PREPAY) || Objects.equals(e.getAmountType(), OrderPayConsts.ORDER_PAY_CHANNEL_PREPAY);
                erpOrderPayDTO.setPreGetType(isPrepayAmt ? GlobalConsts.YES : GlobalConsts.NO);
                erpOrderPayDTOS.add(erpOrderPayDTO);
            });
            newOrderAccountDTO.setOrderPayList(erpOrderPayDTOS);
        }

        // 服务项内外结算价
        List<OrderServiceItem> orderServiceItems = orderServiceItemService.listByOrderId(orderWork.getOrderId());
        int internalSettlementPrice = 0;
        int externalSettlementPrice = 0;
        if (CollectionUtil.isNotNullOrEmpty(orderServiceItems)) {
            internalSettlementPrice = orderServiceItems.stream()
                    .filter(e -> NumberUtil.isNotNullOrZero(e.getInternalTotalPrice()))
                    .mapToInt(OrderServiceItem::getInternalTotalPrice).sum();
            externalSettlementPrice = orderServiceItems.stream()
                    .filter(e -> NumberUtil.isNotNullOrZero(e.getExternalTotalPrice()))
                    .mapToInt(OrderServiceItem::getExternalTotalPrice).sum();
        }
        if (NumberUtil.isNullOrZero(internalSettlementPrice)) {
            internalSettlementPrice = orderWork.getOriginalAmount();
        }
        if (NumberUtil.isNullOrZero(internalSettlementPrice)) {
            externalSettlementPrice = orderWork.getOriginalAmount();
        }

        // 墙面订单处理
        Integer wallCount = wallQuotationService.countByQuery(WallQuotationQuery.builder()
                .workId(orderWork.getWorkId()).orderId(orderWork.getOrderId()).build());
        if (wallCount > com.zmn.consts.GlobalConsts.NONE) {
            externalSettlementPrice = orderWork.getOriginalAmount();
            internalSettlementPrice = orderWork.getOriginalAmount();
        }

        newOrderAccountDTO.setInternalStatementAmount(internalSettlementPrice);
        newOrderAccountDTO.setOutStatementAmount(externalSettlementPrice);
        newOrderAccountDTO.setPartsReimburseStatus(reimburseStatus);

        // 过滤用户名称的特殊字符
        newOrderAccountDTO.setUserName(FilterUtil.replaceSpeChar(newOrderAccountDTO.getUserName()));

        // 特殊加单标志
        newOrderAccountDTO.setSpecialAddOrder(false);
        if (Objects.equals(orderWork.getServCategId(), 1001) && NumberUtil.isNotNullOrZero(orderWork.getRecommenderId()) && Objects.equals(orderWork.getRecommenderType(), GlobalConsts.OPERATE_USER_TYPE_MASTER)) {
            // 判断 录单时间 和 完成时间 是否是同一天
            String receiveTimeStr = DateUtil.toString(orderWork.getReceiveTime(), DateUtil.FORMAT_DATE);
            String completeTimeStr = DateUtil.toString(orderWork.getCompleteTime(), DateUtil.FORMAT_DATE);

            if (Objects.equals(receiveTimeStr, completeTimeStr)) {
                newOrderAccountDTO.setSpecialAddOrder(true);
            }
        }

        // 不考核的范围只针对有剔除标记且订单结果为失败的订单
        Boolean existsTag = orderTagBService.existsCategoryTagByCategoryId(orderWork.getOrderId(), orderWork.getWorkId(),
                OrderTagConsts.TAG_CATEGORY_ID_EXCLUDE_PERFORMANCE);
        if (Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_FAIL) && existsTag) {
            // 设置工单绩效剔除标记
            newOrderAccountDTO.setEliminateTag(Boolean.TRUE);
        } else {
            newOrderAccountDTO.setEliminateTag(Boolean.FALSE);
        }

        // 一口价订单参数处理
        if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
            List<Integer> itemTypeIds = servItemBService.getServItemTypeIdList(OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE);

            OrderServiceItem serviceItem = orderServiceItems.stream()
                    .filter(e -> itemTypeIds.contains(e.getServItemGroupId()))
                    .findFirst()
                    .orElse(null);
            if (Objects.nonNull(serviceItem)) {
                newOrderAccountDTO.setItemTypeId(serviceItem.getServItemGroupId());
                newOrderAccountDTO.setItemTypeName(serviceItem.getServItemGroupName());
            }
        }

        // 根据下单平台与服务平台设置业务模式和合同模式 2022.07.27
        Integer workPlat = platBizModeService.findByPlat(orderWork.getPlatWork());
        newOrderAccountDTO.setBizMode(workPlat);

        Integer plat = platBizModeService.findByPlat(orderWork.getPlat());
        newOrderAccountDTO.setBizModeSource(plat);

        log.info("新单算账请求参数[{}]", newOrderAccountDTO);
        return newOrderAccountDTO;
    }

    @Override
    public ReworkOrderAccountInfoDTO getReworkOrderAccountInfo(OrderWork orderWork) throws OmsBaseException {
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderWork.getOrderId());

        ReworkOrderAccountInfoDTO reworkOrderAccountDTO = new ReworkOrderAccountInfoDTO();
        reworkOrderAccountDTO.setProductInf(orderDetail.getProductInfo());
        reworkOrderAccountDTO.setSourceOrderId(orderWork.getOriginalId());
        reworkOrderAccountDTO.setLastReworkWorkId(orderWork.getReworkId());
        reworkOrderAccountDTO.setOrderId(orderWork.getOrderId());
        reworkOrderAccountDTO.setWorkId(orderWork.getWorkId());
        reworkOrderAccountDTO.setPlatSource(orderWork.getPlat());
        reworkOrderAccountDTO.setPlat(orderWork.getPlatWork());
        reworkOrderAccountDTO.setSubCompanyId(orderWork.getCompanyId());
        reworkOrderAccountDTO.setSubCompanyName(orderWork.getCompanyName());
        reworkOrderAccountDTO.setSpCompanyId(orderWork.getManageCompanyId());
        reworkOrderAccountDTO.setSpCompanyName(orderWork.getManageCompanyName());
        reworkOrderAccountDTO.setReceiveTime(orderWork.getReceiveTime());
        reworkOrderAccountDTO.setCompleteTime(orderWork.getCompleteTime());
        reworkOrderAccountDTO.setProductGroupId(orderWork.getServProductGroupId());
        reworkOrderAccountDTO.setBizType(orderWork.getBizType());
        //Integer reimburseStatus = orderWork.getPartReimburseStatus();
        // 处理工程师信息
        // 当前工单多工程师处理
        // 查询工程师列表
        // 配件信息
        List<OrderPart> orderParts = orderPartService.listByOrderId(orderWork.getOrderId());

        List<OrderMaster> orderMasterList = orderMasterService.listMasterByWorkId(orderWork.getOrderId(), orderWork.getWorkId());
        Map<Integer, List<OrderPart>> partMap = orderParts.stream()
                .collect(Collectors.groupingBy(OrderPart::getMasterId));

        List<OrderAccountEngineerDTO> multiMasters = new ArrayList<>(orderMasterList.size());
        orderMasterList.forEach(orderMaster -> {
            OrderAccountEngineerDTO engineerDTO = new OrderAccountEngineerDTO();
            engineerDTO.setEngineerId(orderMaster.getMasterId());
            engineerDTO.setEngineerName(orderMaster.getMasterName());
            engineerDTO.setMajorEngineer(Objects.equals(orderMaster.getType(), OrderConsts.ORDER_MASTER_TYPE_MAIN));
            if (Objects.equals(orderWork.getMultiMaster(), GlobalConsts.YES)) {
                engineerDTO.setShareRate(orderMaster.getShareRateBigDecimal());
            } else {
                engineerDTO.setShareRate(new BigDecimal(100));
            }

            List<OrderPart> orderMasterParts = partMap.get(orderMaster.getMasterId());
            if (CollectionUtil.isNotNullOrEmpty(orderMasterParts)) {
                // 内采&非质保金购买
                Integer noDepositpartAmount = orderMasterParts.stream().filter(part -> Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_IN) && !Objects.equals(part.getPayType(), OrderPartConsts.DEPOSIT_PAY)).mapToInt(part -> {
                    return MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber());
                }).sum();
                // 内采&非质保金购买
                Integer masterSupPartAmount = orderMasterParts.stream().filter(part -> Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_IN) && Objects.equals(part.getPayType(), OrderPartConsts.DEPOSIT_PAY)).mapToInt(part -> {
                    return MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber());
                }).sum();

                engineerDTO.setPartAmount(noDepositpartAmount);
                engineerDTO.setPartAmountFromSup(masterSupPartAmount);

                // 非内采配件
                Integer otherPartAmount = orderMasterParts.stream().filter(part -> !Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_IN)).mapToInt(part -> {
                    return MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber());
                }).sum();
                engineerDTO.setOtherPartAmount(otherPartAmount);

                // 配件结算主体
                // 现金内采配件结算主体
                List<OrderPartSettleSubjectInfo> cashInsourcingPartAmountList = orderMasterParts.stream().filter(part -> {
                    return Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_IN) && !Objects.equals(part.getPayType(), OrderPartConsts.DEPOSIT_PAY);
                }).map(part -> {
                    OrderPartSettleSubjectInfo dio = new OrderPartSettleSubjectInfo();
                    dio.setPartsReimburseStatus(part.getReimburseStatus());
                    dio.setPartAmount(MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber()));
                    dio.setSettlementSubjectType(part.getSettlementSubjectType());
                    return dio;
                }).collect(Collectors.toList());
                engineerDTO.setCashInsourcingPartAmountList(cashInsourcingPartAmountList);

                // 外报配件结算主体
                List<OrderPartSettleSubjectInfo> outsourcingPartAmountList = orderMasterParts.stream().filter(part -> {
                    return Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_SOURCING_OUT);
                }).map(part -> {
                    OrderPartSettleSubjectInfo dio = new OrderPartSettleSubjectInfo();
                    dio.setPartsReimburseStatus(part.getReimburseStatus());
                    dio.setPartAmount(MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber()));
                    dio.setSettlementSubjectType(part.getSettlementSubjectType());
                    return dio;
                }).collect(Collectors.toList());
                engineerDTO.setOutsourcingPartAmountList(outsourcingPartAmountList);

                // 订单杂项费用结算主体
                List<OrderPartSettleSubjectInfo> otherPartAmountList = orderMasterParts.stream()
                        .filter(part -> Objects.equals(part.getPartType(), OrderConsts.PART_TYPE_DELIVER))
                        .map(part -> {
                            OrderPartSettleSubjectInfo dio = new OrderPartSettleSubjectInfo();
                            dio.setPartsReimburseStatus(part.getReimburseStatus());
                            dio.setPartAmount(MathUtil.amountMultiplyNumber(part.getPrice(), part.getNumber()));
                            dio.setSettlementSubjectType(part.getSettlementSubjectType());
                            return dio;
                        })
                        .collect(Collectors.toList());
                engineerDTO.setOtherPartAmountList(otherPartAmountList);
            }

            multiMasters.add(engineerDTO);
        });

        // 查询完成后的新一次返修单
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .filter(QueryBuilders.rangeQuery("status").gte(OrderStatusConsts.WORK_STATUS_COMPLETE))
                .filter(QueryBuilders.rangeQuery("receiveTime").lt(DateUtil.toString(orderWork.getReceiveTime())))
                .filter(QueryBuilders.termQuery("type", OrderConsts.ORDER_TYPE_REWORK))
                .filter(QueryBuilders.termQuery("reworkId", orderWork.getReworkId()));
        NativeSearchQuery searchQuery = new NativeSearchQuery(queryBuilder);
        searchQuery.setPageable(PageRequest.of(0, 1, Sort.by(Sort.Order.desc("receiveTime"))));
        searchQuery.addSourceFilter(new FetchSourceFilterBuilder().withIncludes("orderId").build());
        List<EsOrderWork> page = orderWorkEsBService.listPageByQuery(searchQuery);
        if (CollectionUtil.isNotNullOrEmpty(page)) {
            reworkOrderAccountDTO.setLastReworkWorkId(page.get(0).getOrderId());
        }
        reworkOrderAccountDTO.setEngineers(multiMasters);
        reworkOrderAccountDTO.setPartsReimburseStatus(orderWork.getPartReimburseStatus());
        return reworkOrderAccountDTO;
    }

    @Override
    public RefundOrderAccountInfoDTO getRefundOrderAccountInfo(OrderWork orderWork) {
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKeySrcMaster(orderWork.getOrderId());
        OrderExtend orderExtend = orderExtendService.findOrderExtendByOrderId(orderWork.getOrderId());

        RefundOrderAccountInfoDTO accountDTO = new RefundOrderAccountInfoDTO();
        accountDTO.setSourceWorkId(orderWork.getOrderId());
        accountDTO.setOrderId(orderWork.getOrderId());
        accountDTO.setWorkId(orderWork.getWorkId());
        accountDTO.setPlat(orderWork.getPlatWork());
        accountDTO.setServCategId(orderWork.getServCategId());
        accountDTO.setServCategName(orderWork.getShowServCategName());
        accountDTO.setRefundAmount(orderWork.getRefundAmount() + Math.abs(Optional.ofNullable(orderWork.getDiscountPrepayAmount()).orElse(0)));
        accountDTO.setRefundCustomerName(orderDetail.getUserName());
        accountDTO.setReceiveTime(orderWork.getReceiveTime());
        accountDTO.setManageCompanyId(orderWork.getManageCompanyId());
        if (Objects.nonNull(orderExtend)) {
            accountDTO.setAllowRefund(orderExtend.getAllowRefund());
        }
        accountDTO.setProductInf(orderDetail.getProductInfo());

        List<OrderMaster> orderMasterList = orderMasterService.listMasterByWorkId(orderWork.getOrderId(), orderWork.getOrderId());
        List<OrderAccountEngineerDTO> multiMasters = new ArrayList<>(orderMasterList.size());
        orderMasterList.forEach(orderMaster -> {
            OrderAccountEngineerDTO engineerDTO = new OrderAccountEngineerDTO();
            engineerDTO.setEngineerId(orderMaster.getMasterId());
            engineerDTO.setEngineerName(orderMaster.getMasterName());
            engineerDTO.setMajorEngineer(Objects.equals(orderMaster.getType(), OrderConsts.ORDER_MASTER_TYPE_MAIN));
            multiMasters.add(engineerDTO);
        });
        accountDTO.setEngineers(multiMasters);

        // 退款单渠道差评
        List<OrderRemarkDetail> remarkDetailList = orderRemarkDetailService.listOrderRemarkDetailByRemarkId(orderWork.getOrderId(), orderWork.getWorkId(), null);
        if (CollectionUtil.isNotNullOrEmpty(remarkDetailList)) {
            boolean hasChannelBadComment = remarkDetailList.stream().anyMatch(e -> Objects.equals(e.getType(), OrderConsts.ORDER_REMARK_TYPE_REFUND) && Objects.equals(e.getMapId(), OrderRefundConsts.REFUND_REASON_CHANNEL_BAD_COMMENT));
            accountDTO.setHasChannelBadComment(hasChannelBadComment ? com.zmn.consts.GlobalConsts.YES : com.zmn.consts.GlobalConsts.NO);
        }
        return accountDTO;
    }

    @Override
    public CompensateOrderAccountInfoDTO getCompensateOrderAccountInfo(OrderWork orderWork) {
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKeySrcMaster(orderWork.getOrderId());
        CompensateOrderAccountInfoDTO compensateOrderAccountInfoDTO = new CompensateOrderAccountInfoDTO();
        compensateOrderAccountInfoDTO.setSourceWorkId(orderWork.getOrderId());
        compensateOrderAccountInfoDTO.setWorkId(orderWork.getWorkId());
        compensateOrderAccountInfoDTO.setOrderId(orderWork.getOrderId());
        compensateOrderAccountInfoDTO.setPlat(orderWork.getPlatWork());
        compensateOrderAccountInfoDTO.setServCategId(orderWork.getServCategId());
        compensateOrderAccountInfoDTO.setServCategName(orderWork.getShowServCategName());
        compensateOrderAccountInfoDTO.setProductInf(orderDetail.getProductInfo());
        compensateOrderAccountInfoDTO.setAmount(Math.abs(orderWork.getTotalAmount()));
        compensateOrderAccountInfoDTO.setCustomerName(orderDetail.getUserName());
        compensateOrderAccountInfoDTO.setOrderTime(orderWork.getReceiveTime());
        // 工程师
        List<OrderMaster> orderMasterList = orderMasterService.listMasterByWorkId(orderWork.getOrderId(), orderWork.getWorkId());
        List<OrderAccountEngineerDTO> multiMasters = new ArrayList<>(orderMasterList.size());
        orderMasterList.forEach(orderMaster -> {
            OrderAccountEngineerDTO engineerDTO = new OrderAccountEngineerDTO();
            engineerDTO.setEngineerId(orderMaster.getMasterId());
            engineerDTO.setEngineerName(orderMaster.getMasterName());
            engineerDTO.setMajorEngineer(Objects.equals(orderMaster.getType(), OrderConsts.ORDER_MASTER_TYPE_MAIN));
            multiMasters.add(engineerDTO);
        });
        compensateOrderAccountInfoDTO.setEngineers(multiMasters);

        // 是否已支付
        List<OrderPay> orderPays = orderPayService.listOrderPayByOrderIdAndWorkId(orderWork.getOrderId(), orderWork.getOrderId());
        boolean isPayed = orderPays
                .stream()
                .anyMatch(e -> {
                    return Objects.equals(e.getTradeType(), PayConsts.PAY_TRADE_TYPE_INTIME) && Objects.equals(e.getPayStatus(), PayConsts.PAY_STATUS_DONE);
                });
        compensateOrderAccountInfoDTO.setPayed(isPayed);

        // 源单状态
        OrderWork originOrderWork = orderWorkService.findOrderWorkByKey(orderWork.getOrderId(), orderWork.getOrderId());
        compensateOrderAccountInfoDTO.setOriginOrderStatus(originOrderWork.getResultStatus());
        compensateOrderAccountInfoDTO.setSourceOrderStatus(originOrderWork.getStatus());

        return compensateOrderAccountInfoDTO;
    }
}
